﻿using KWT.DRG_DIP.API.Infrastructure;
using KWT.DRG_DIP.Common;
using KWT.DRG_DIP.DB;
using KWT.DRG_DIP.DO.System;
using KWT.DRG_DIP.DTO.Basic.Dept;
using KWT.DRG_DIP.ISvc;
using KWT.DRG_DIP.PO.Basic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using OfficeOpenXml;
using System.Diagnostics.Eventing.Reader;
using Yitter.IdGenerator;

namespace KWT.DRG_DIP.API.Controllers.Basic
{
    /// <summary>
    /// 科室管理
    /// </summary>
    [ApiExplorerSettings(GroupName = "basic")]
    public class CategoryController : BasicControllerBase
    {
        public EFContext ef { get; set; }
        /// <summary>
        /// 添加或修改
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<string>), 200)]
        public OutputResult AddOrUpdate(InAddOrUpdate dto)
        {
            if (string.IsNullOrWhiteSpace(dto.CategoryID))
            {
                var dept = new Sys_Category()
                {
                    CategoryID = "CT" + snow_id.CreateId().ToString(),
                    Code = dto.Code,
                    Name = dto.Name,
                    PID = dto.IsGroup ? "1" : "",
                    Code1 = dto.Code1,
                    Name1 = dto.Name1,
                    IsGroup = dto.IsGroup,
                    AreaID = dto.AreaID,
                };
                ef.Add(dept);
            }
            else
            {
                var dept = ef.Find<Sys_Category>(dto.CategoryID);
                if (dept == null) { return Fail("未找到该项"); }
                if (dto.IsGroup)
                {
                    dept.PID = "1";
                }
                dept.Code = dto.Code;
                dept.Name = dto.Name;
                dept.Code1 = dto.Code1;
                dept.Name1 = dto.Name1;
                dept.IsGroup = dto.IsGroup;
                dept.AreaID = dto.AreaID;
                dept.UpdTime = DateTime.Now;
                ef.Attach(dept);
            }
            var flag = ef.SaveChanges() > 0;
            return Output(flag, "操作成功！", "操作失败！");
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="dto">科室主键集合</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<string>), 200)]
        public OutputResult Del(InDel dto)
        {
            var dept = ef.Set<Sys_Category>().Where(x => dto.CategoryIDs.Contains(x.CategoryID)).ToList();
            dept.ForEach(x => x.IsDel = true);
            ef.AttachRange(dept);
            var flag = ef.SaveChanges() > 0;
            return Output(flag, "删除成功", "删除失败");
        }

        /// <summary>
        /// 树形菜单（当前用户）
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(Output<List<OutTree>>), 200)]
        public OutputResult TreeListByUser([FromQuery] string areaID)
        {
            var user = CurrentUser;
            List<Sys_Category> all;
            if (user.IsAuth)
            {
                user.CategoryIDs.Add("1");
                all = ef.Set<Sys_Category>().Where(x => user.CategoryIDs.Contains(x.CategoryID)).AsNoTracking().ToList();
            }
            else
            {
                all = ef.Set<Sys_Category>().Where(x => x.AreaID == areaID).AsNoTracking().ToList();
            }
            var dic = new Dictionary<string, OutTree>(all.Count);

            foreach (var trade in all)
            {
                var tree = new OutTree()
                {
                    Title = trade.Name,
                    CategoryID = trade.CategoryID,
                    PID = trade.PID,
                    IsGroup = trade.IsGroup
                };
                dic.Add(trade.CategoryID, tree);
            }

            //通过一次遍历集合，转换成具有层次结构的类型
            foreach (var menu in dic.Values)
            {
                if (dic.ContainsKey(menu.PID))
                {
                    if (dic[menu.PID].children == null)
                        dic[menu.PID].children = [];

                    dic[menu.PID].children.Add(menu);
                }
            }

            //仅仅选择最顶层节点返回
            var list = dic.Values.Where(t => t.PID == "").ToList();
            return Output(true, "", "", list);
        }

        /// <summary>
        /// 树形菜单（后台管理用）
        /// </summary>
        /// <param name="areaID">院区ID</param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(Output<List<OutTree>>), 200)]
        public OutputResult TreeList([FromQuery] string areaID)
        {
            var all = ef.Set<Sys_Category>().Where(x => x.AreaID == areaID).ToList();
            var dic = new Dictionary<string, OutTree>(all.Count);

            foreach (var trade in all)
            {
                var tree = new OutTree()
                {
                    Title = trade.Name,
                    CategoryID = trade.CategoryID,
                    PID = trade.PID,
                    IsGroup = trade.IsGroup
                };
                dic.Add(trade.CategoryID, tree);
            }

            //通过一次遍历集合，转换成具有层次结构的类型
            foreach (var menu in dic.Values)
            {
                if (dic.ContainsKey(menu.PID))
                {
                    if (dic[menu.PID].children == null)
                        dic[menu.PID].children = [];

                    dic[menu.PID].children.Add(menu);
                }
            }

            //仅仅选择最顶层节点返回
            var list = dic.Values.Where(t => t.PID == "").ToList();
            return Output(true, "", "", list);
        }

        /// <summary>
        /// 分页列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<List<OutPageList>>), 200)]
        public OutputResult PageList(InPageList dto)
        {
            var q1 = ef.Set<Sys_Category>().AsQueryable();
            var q2 = ef.Set<Tenant_Area>().AsQueryable();
            if (!string.IsNullOrWhiteSpace(dto.AreaID))
            {
                q1 = q1.Where(x => x.AreaID == dto.AreaID);
            }
            if (!string.IsNullOrWhiteSpace(dto.CategoryName))
            {
                q1 = q1.Where(x => EF.Functions.Like(x.Name, $"%{dto.CategoryName}%"));
            }
            if (!string.IsNullOrWhiteSpace(dto.CategoryGroupName))
            {
                q1 = q1.Where(x => EF.Functions.Like(x.Name, $"%{dto.CategoryGroupName}%") && x.IsGroup == true);
            }
            var _q = from x in q1
                     join y in q2 on x.AreaID equals y.AreaID
                     orderby x.AddTime descending
                     select new OutPageList()
                     {
                         AreaID = x.AreaID,
                         AreaName = y.Name,
                         Name = x.Name,
                         Code = x.Code,
                         Code1 = x.Code1,
                         Code2 = x.Code2,
                         CategoryID = x.CategoryID,
                         IsGroup = x.IsGroup,
                         Name1 = x.Name1,
                         Name2 = x.Name2,
                         PID = x.PID,
                         AddTime = x.AddTime,
                         UpdTime = x.UpdTime,
                     };
            int total = _q.Count();
            var list = _q.ToPageList(dto.PageNo, dto.PageSize);
            return Output(list.Count > 0, "", "", new PageList<OutPageList>() { Total = total, List = list });
        }

        /// <summary>
        /// 归为医疗组
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public OutputResult JoinGroup(InJoinGroup dto)
        {
            var depts = ef.Set<Sys_Category>().Where(x => dto.CategoryIDs.Contains(x.CategoryID)).ToList();
            if (depts.Any(x => x.IsGroup))
            {
                return Fail("选中的科室中含有医疗组！");
            }
            if (depts == null)
            {
                return Fail("未选中任何项！");
            }
            depts.ForEach(x => x.PID = dto.CategoryID);
            ef.AttachRange(depts);
            var flag = ef.SaveChanges() > 0;
            return Output(flag, "操作成功", "操作失败");
        }

        /// <summary>
        /// 批量导入
        /// </summary>
        /// <param name="file">excel文件</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<string>), 200)]
        public OutputResult Import(IFormFile file)
        {
            using var pkg = new ExcelPackage(file.OpenReadStream());
            var worksheet = pkg.Workbook.Worksheets[0];

            var list = worksheet.Dimension.ToCollectionWithMappings(row =>
            {
                var para = new Sys_Category
                {
                    AreaID = row.GetValue<string>("院区编码"),
                    Code = row.GetValue<string>("院内科室代码"),
                    Code1 = row.GetValue<string>("标准科室代码"),
                    Name = row.GetValue<string>("院内科室名称"),
                    Name1 = row.GetValue<string>("标准科室名称"),
                    PID = row.GetValue<bool>("是否医疗组") ? "1" : "",
                    IsGroup = row.GetValue<bool>("是否医疗组"),
                };
                return para;
            }, options => options.HeaderRow = 0);
            var idGeneratorOptions = new Yitter.IdGenerator.IdGeneratorOptions(1) { SeqBitLength = 10 };
            YitIdHelper.SetIdGenerator(idGeneratorOptions);
            list.ForEach(x =>
            {
                x.CategoryID = "CG" + YitIdHelper.NextId().ToString();
            });
            ef.AddRange(list);
            var flag = ef.SaveChanges() > 0;
            return Output(flag, "操作成功", "操作失败");
        }

        /// <summary>
        /// 科别列表（级联组件用）
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public OutputResult CascaderList([FromQuery] string areaID)
        {
            var list = ef.Set<Sys_Category>().Where(x => x.AreaID == areaID && x.Name != "全科医学").Select(x => new { label = x.Name, value = x.CategoryID }).ToList();
            return Output(list.Count > 0, "", "", list);
        }

        /// <summary>
        /// 根据关键字模糊查询
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public OutputResult SelectList([FromQuery] string keyword)
        {
            string areaID = CurrentUser.AreaIDs.First();
            if (string.IsNullOrWhiteSpace(keyword))
            {
                var list = ef.Set<Sys_Category>().Where(x => x.AreaID == areaID).Select(x => new { label = x.CategoryID, value = x.Name }).AsNoTracking().ToList();
                return Output(list.Count > 0, "", "", list);
            }
            else
            {
                var list = ef.Set<Sys_Category>().Where(x => x.AreaID == areaID && EF.Functions.Like(x.Name, $"%{keyword}%")).Select(x => new { label = x.CategoryID, value = x.Name }).AsNoTracking().ToList();
                return Output(list.Count > 0, "", "", list);
            }
        }
    }
}
